#!/usr/bin/perl

use Getopt::Long qw(:config auto_version);
use Image::MetaData::JPEG;
use Pod::Usage;
use Term::ProgressBar;

use strict;
use warnings;


my $opt_debug;

{
  $main::VERSION = "1.0.0";
  pod2usage(-verbose => 1) if @ARGV == 0;

  my ($opt_segments, $opt_directory);

  GetOptions(
             "segments=s" => \$opt_segments,
             "directory=s" => \$opt_directory,
             "debug" => \$opt_debug,
            );

  pod2usage(verbose => 1,
            message => "missing required --segments option") unless defined $opt_segments;

  print "files will be written to $opt_directory\n" if defined $opt_directory;

  my @segments = split(/, /, $opt_segments);

  debug("segments: ".join(", ", @segments));

  my $files = {};
  find_files($files, \@ARGV);

  my $progress = Term::ProgressBar->new ({
                                          name => "strip",
                                          count => scalar(keys %$files),
                                          ETA   => "linear",
                                          term_width => 80,
                                          max_update_rate => .1,
                                         });

  map { strip_metadata($_, \@segments, $opt_directory); $progress->update(); } keys %$files;

  $progress->update(scalar(scalar(keys %$files)));
  print "\n";
}

sub find_files {
  my ($hash, $list) = @_;
  for my $arg (@$list) {
    if (-d $arg) {
      my @children = <$arg/*>;
      find_files($hash, \@children);
    } elsif ($arg =~ m/\.jpg$/) {
      $hash->{$arg}++;
    }
  }
}


sub debug {
  my ($msg) = @_;
  print STDERR "debug> ".$msg."\n" if $opt_debug;
}


sub strip_metadata {
  my ($file, $segments, $directory) = @_;

  if (-d $file) {
    for (<$file/*.jpg>) {
      strip_metadata($_, $segments, $directory);
    }
    return;
  }

  my ($file_name) = $file =~ /^.*\/(.*)$/;
  $file_name = $file unless defined $file_name;
  my $jpg = new Image::MetaData::JPEG($file);
  if (!defined $jpg) {
    print STDERR "error processing $file: ".Image::MetaData::JPEG::Error()."\n";
    return;
  }
  for (@$segments) {
    my $segment = $_ eq "ALL" ? "METADATA" : $_;
    $jpg->drop_segments($segment);
  }
  my $outfile = defined $directory ? "$directory/$file_name" : undef;
  debug("writing file to $outfile") if defined $outfile;
  print STDERR "failed to save $outfile: ".Image::MetaData::JPEG::Error()."\n" unless $jpg->save($outfile);
}




__END__

=head1 jpeg-strip-metadata [options] <files>

=head1 SYNOPSIS

jpeg-strip-metadata [options] file-1.jpg ... file-n.jpg


=head1 OPTIONS

 --directory=<dir>

     This specifies the directory to which newly-stripped files
     should be written.  The default is the directory the file
     is in and in that case will overwrite the original file.

 --segments=<segments>

     The argument here should be a list of segments to strip from
     the jpeg files.  The list should be comma-separated and can
     include things like APP1, APP2, APP13, COM, etc.

     The segment ALL specifies all APP* and COM segments.

=head1 DESCRIPTION

=cut

